home *** CD-ROM | disk | FTP | other *** search
/ C/C++ Users Group Library 1996 July / C-C++ Users Group Library July 1996.iso / vol_400 / 428_02 / libsrc / uncomp.c < prev    next >
Encoding:
C/C++ Source or Header  |  1994-03-13  |  2.4 KB  |  134 lines

  1. /*
  2. ** uncomp.c
  3. **
  4. ** Pictor, Version 1.51, Copyright (c) 1992-94 SoftCircuits
  5. ** Redistributed by permission.
  6. */
  7.  
  8. #include <stdlib.h>
  9. #include "compress.h"
  10.  
  11.  
  12. /* variable declarations */
  13. static BYTE *buffer;
  14. static WORD index;
  15. static BYTE curr_bit;
  16.  
  17.  
  18. /*
  19. ** Returns the next available bit value from buffer.
  20. */
  21. static BYTE read_bit(void)
  22. {
  23.     BYTE bit;
  24.  
  25.     if(curr_bit == 0) {
  26.         index++;
  27.         curr_bit = 1;
  28.     }
  29.  
  30.     bit = (BYTE)((buffer[index] & curr_bit) ? 1 : 0);
  31.  
  32.     curr_bit <<= 1;
  33.  
  34.     return(bit);
  35.  
  36. } /* read_bit */
  37.  
  38. /*
  39. ** Uncompresses a compressed buffer. len specifies the
  40. ** uncompressed length.
  41. */
  42. void uncompress(BYTE *in_array,WORD len,BYTE *out_array,NODE *root)
  43. {
  44.     WORD i;
  45.     NODE *node_ptr;
  46.  
  47.     buffer = in_array;   /* set variables for read_bit() */
  48.     index = 0;
  49.     curr_bit = 1;
  50.  
  51.     for(i = 0;i < len;i++) {
  52.         node_ptr = root;
  53.         while(node_ptr->child0 != NULL) {
  54.             if(read_bit() == 0) {
  55.                 node_ptr = node_ptr->child0;
  56.             }
  57.             else {
  58.                 node_ptr = node_ptr->child1;
  59.             }
  60.         }
  61.         out_array[i] = node_ptr->c;
  62.     }
  63.  
  64. } /* uncompress */
  65.  
  66. /*
  67. ** Combines two child nodes into a single branch node and returns a
  68. ** pointer to the branch. NULL indicates memory error.
  69. */
  70. static NODE *build_branch(NODE *child0,NODE *child1)
  71. {
  72.     NODE *node_ptr;
  73.  
  74.     node_ptr = malloc(sizeof(NODE));
  75.     if(node_ptr != NULL) {
  76.         node_ptr->child0 = child0;
  77.         node_ptr->child1 = child1;
  78.     }
  79.     else {
  80.         freetree(child0);
  81.         freetree(child1);
  82.     }
  83.     return(node_ptr);
  84.  
  85. } /* build_branch */
  86.  
  87. /*
  88. ** Recursive portion of readtree().
  89. **
  90. ** This function takes care that all memory gets freed upon failure.
  91. */
  92. static NODE *_readtree(void)
  93. {
  94.     NODE *node_ptr,*child0,*child1;
  95.     int i;
  96.  
  97.     if(read_bit() == 1) {
  98.         child0 = _readtree();
  99.         if(child0 == NULL)
  100.             return(NULL);
  101.         child1 = _readtree();
  102.         if(child1 == NULL) {
  103.             freetree(child0);
  104.             return(NULL);
  105.         }
  106.         node_ptr = build_branch(child0,child1);
  107.     }
  108.     else {
  109.         node_ptr = malloc(sizeof(NODE));
  110.         if(node_ptr != NULL) {
  111.             for(node_ptr->c = 0,i = 0;i < 8;i++)
  112.                 node_ptr->c |= (read_bit() << i);
  113.             node_ptr->child0 = NULL;
  114.             node_ptr->child1 = NULL;
  115.         }
  116.     }
  117.     return(node_ptr);
  118.  
  119. } /* _readtree */
  120.  
  121. /*
  122. ** Constructs a code tree from in_array and returns a pointer to
  123. ** the root node, NULL indicates memory error.
  124. */
  125. NODE *readtree(BYTE *in_array)
  126. {
  127.     buffer = in_array;   /* set variables for read_bit() */
  128.     index = 0;
  129.     curr_bit = 1;
  130.  
  131.     return(_readtree());
  132.  
  133. } /* readtree */
  134.